package com.gxkj.projects.myshopx.handler;

import com.alibaba.fastjson.JSON;
import com.gxkj.common.dto.BaseError;
import com.gxkj.common.exceptions.AuthorityException;
import com.gxkj.common.exceptions.BusinessException;
import com.gxkj.common.exceptions.ValidateException;
import com.gxkj.projects.myshopx.dto.ReturnData;
import com.gxkj.projects.myshopx.enums.ErrorCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;

/**
 * Created by xubaoyong on 2016/3/5.
 */
public class MyExceptionHandler extends SimpleMappingExceptionResolver {

    private  static Logger LOG = LoggerFactory.getLogger(MyExceptionHandler.class);

    protected ModelAndView doResolveException(HttpServletRequest request,
                                              HttpServletResponse response, Object handler, Exception ex) {
        String viewName = determineViewName(ex, request);
        LOG.info("error");
        ex.printStackTrace();

        if (!StringUtils.isEmpty(viewName)) {// JSP格式返回
            if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
                    .getHeader("X-Requested-With")!= null && request
                    .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1)
                    || request.getParameter("isAjax") != null
                    )) {
                // 如果不是异步请求
                // Apply HTTP status code for error views, if specified.
                // Only apply it if we're processing a top-level request.
                request.setAttribute("ex",ex);
                return getModelAndView(viewName, ex, request);
            } else {// JSON格式返回
                if (ex instanceof ValidateException){
                    ValidateException exception = (ValidateException)ex;
                    if(exception.isSingle()){

                        return doGetErrorView(ErrorCodeEnum.VALID_FIELD_ERROR.toString(),ErrorCodeEnum.VALID_FIELD_ERROR.toString(),exception.getValidateDescDto().getErrorMsg());
                    }else {
                        return doGetErrorView(ErrorCodeEnum.VALID_FIELD_ERROR.toString(),ErrorCodeEnum.VALID_FIELD_ERROR.toString(),exception.getValidateDescDtos().get(0).getErrorMsg());
                    }
                }else if(ex instanceof BusinessException){
                    BusinessException  exception = (BusinessException)ex;

                    return doGetErrorView(exception.getStatusCode(),exception.getStatusCode(),exception.getErrorMsg());

                }else if(ex instanceof  java.sql.SQLException){
//
//                    SQLException exception = (SQLException)ex;

                    return doGetErrorView(ErrorCodeEnum.SYSTEM_ERROR.getCode(),ErrorCodeEnum.SYSTEM_ERROR.getCode(),ErrorCodeEnum.SYSTEM_ERROR.getMsg());

                }else  if (ex instanceof AuthorityException){
//                    AuthorityException exception = (AuthorityException)ex;
                    return doGetErrorView(ErrorCodeEnum.NOAUTHORITY_ERROR.getCode(),ErrorCodeEnum.NOAUTHORITY_ERROR.getCode(),ErrorCodeEnum.NOAUTHORITY_ERROR.getMsg());

                }
                return null;
            }
        }
        return getModelAndView(viewName, ex, request);

    }



    private ModelAndView doGetErrorView(String statesCode,String errorCode,String errorMsg)  {

        ReturnData<BaseError> errorData = new ReturnData<BaseError>();
        errorData.setStatusCode(statesCode);
        BaseError errorEntity = new BaseError();
        errorEntity.setErrorCode(errorCode);
        errorEntity.setErrorMsg(errorMsg);
        errorData.setEntity(errorEntity);

        ModelAndView mv = new ModelAndView();
        mv.setViewName("common/ajax_error");
        mv.addObject("data",errorData);

        return mv;
    }
}
